package com.binhthuan.catechist.client;

import com.smartgwt.client.core.KeyIdentifier;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.MenuItemIfFunction;
import com.smartgwt.client.widgets.menu.events.ClickHandler;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

/**
 * @author Giang Đinh - Lớp này tạo menu context cho các tab (menu xuất hiện khi
 *         người dùng nhấp chuột phải vào tên tab).
 * 
 */
public class ContextMenu extends Menu {

    private TabSet tabPanel;
    private int disabledItemIndex;

    /**
     * Khởi tạo.
     * 
     * @param tabPanel
     *            Panel chứa các tab.
     */
    public ContextMenu(TabSet tabPanel) {
        super();
        this.tabPanel = tabPanel;
        disabledItemIndex = -1;
        initMenuItems();
    }

    /**
     * Khởi tạo.
     * 
     * @param tabPanel
     *            Panel chứa các tab.
     * @param disableItemIndex
     *            Chỉ số của tab không sử dụng menu này. Lưu ý:
     *            <i>disableItenIndex</i> = 1: tab 0 và tab 1 sẽ không sử dụng
     *            menu này. <i>disableItemIndex</i> < 0: tất cả các tab đều sử
     *            dụng menu này.
     */
    public ContextMenu(TabSet tabPanel, int disableItemIndex) {
        super();
        this.tabPanel = tabPanel;
        this.disabledItemIndex = disableItemIndex;
        initMenuItems();
    }

    private void initMenuItems() {
        this.setWidth(140);

        if (tabPanel == null) {
            return;
        }

        MenuItemIfFunction enableCondition = new MenuItemIfFunction() {

            @Override
            public boolean execute(Canvas target, Menu menu, MenuItem item) {
                int selectedTabIndex = tabPanel.getSelectedTabNumber();

                if (disabledItemIndex < 0) {
                    return true;
                } else if (selectedTabIndex <= disabledItemIndex) {
                    return false;
                }

                return true;
            }
        };

        // Tạo menu item "Close"
        MenuItem closeMenu = new MenuItem(ECApplication.getConstants().close());
        closeMenu.setEnableIfCondition(enableCondition);
        closeMenu.setKeyTitle("Alt+C");

        // Thiết lập phím tắt cho menu item "Close" là "Alt+C"
        KeyIdentifier shortcutKey = new KeyIdentifier();
        shortcutKey.setAltKey(true);
        shortcutKey.setKeyName("C");
        closeMenu.setKeys(shortcutKey);

        // Khi người dùng đóng tab thì sẽ kích hoạt tab đứng trước nó
        closeMenu.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(MenuItemClickEvent event) {
                clickCloseMenu();
            }
        });

        // Tạo menu item "Close Others"
        MenuItem closeOthers = new MenuItem(ECApplication.getConstants().closeOthers());
        closeOthers.setEnableIfCondition(enableCondition);
        // Khi chọn menu "Close Others", đóng tất cả các tab còn lại ngoại trừ
        // tab hiện hành.
        closeOthers.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(MenuItemClickEvent event) {
                clickCloseOtherMenu();
            }
        });

        // Tạo menu item "Close All"
        MenuItem closeAll = new MenuItem(ECApplication.getConstants().closeAll());
        closeAll.setEnableIfCondition(enableCondition);
        // Khi chọn menu item "Close All" đóng tất cả các tab
        closeAll.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(MenuItemClickEvent event) {
                clickCloseAllMenu();
            }
        });

        // Thêm 3 menu item trên vào menu
        setItems(closeMenu, closeOthers, closeAll);
    }

    /**
     * Click menu <b>Close</b>
     */
    public void clickCloseMenu() {
        int selectedTabIndex = tabPanel.getSelectedTabNumber();
        tabPanel.removeTab(selectedTabIndex);
        tabPanel.selectTab(selectedTabIndex - 1);
    }

    /**
     * Click menu <b>Close Other</b>
     */
    public void clickCloseOtherMenu() {
        int selectedTabIndex = tabPanel.getSelectedTabNumber();
        Tab[] tabs = tabPanel.getTabs();
        int removedTabLength = disabledItemIndex < 0 ? tabs.length - 1 : tabs.length - disabledItemIndex - 2;
        int[] tabsToRemove = new int[removedTabLength];
        int cnt = 0;

        for (int i = disabledItemIndex + 1; i < tabs.length; i++) {
            if (i != selectedTabIndex) {
                tabsToRemove[cnt] = i;
                cnt++;
            }
        }
        tabPanel.removeTabs(tabsToRemove);
    }

    /**
     * Click menu <b>Close All</b>
     */
    public void clickCloseAllMenu() {
        int startIndex = disabledItemIndex < 0 ? 0 : disabledItemIndex + 1;
        int numTabs = tabPanel.getNumTabs();
        for (int i = startIndex; i < numTabs; i++) {
            tabPanel.removeTab(startIndex);
        }

        if (disabledItemIndex >= 0) {
            tabPanel.selectTab(disabledItemIndex);
        }
    }
}
